{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Explanation of Units\n",
    "\n",
    "The units for properties, pore-scale models and any variable used in OpenPNM are based on SI units. Therefore, it is important to assign values to the variables based on SI units. This notebook provides examples of some of the variables used in OpenPNM with their corresponding units and demonstrates the challenges related to units and unit conversions. As an example the units of some parameters used in OpenPNM are shown in following table:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Parameter    | Unit    |\n",
    "|---:| :-------------|\n",
    "| network spacing | $m$       |\n",
    "| pore.diameter | $m$       |\n",
    "| pore.pressure | $Pa$       |\n",
    "| pore.emperature | $K$     |\n",
    "| pore.volume | $m^3$     |\n",
    "| pore.viscosity | $Pa.s$  |\n",
    "| pore.diffusivity | $m^2/s$  |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use of absolute pressure vs gauge pressure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To demonstrate the importance of defining parameter values with correct units, a pore-scale model is examined in this section."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import openpnm as op\n",
    "op.visualization.set_mpl_style()\n",
    "np.random.seed(10)\n",
    "%matplotlib inline\n",
    "np.set_printoptions(precision=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn = op.network.Cubic(shape=[15, 15, 15], spacing=1e-6)\n",
    "pn.add_model_collection(op.models.collections.geometry.spheres_and_cylinders)\n",
    "pn.regenerate_models()\n",
    "phase = op.phase.Phase(network=pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Phase` class in op.phase creates a generic phase with default temperature=298 K and pressure=101325.0 Pa. We can now define a viscosity model to assign 'pore.viscosity' values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mean of water viscosity is: 0.893 mPa.s\n"
     ]
    }
   ],
   "source": [
    "phase.add_model(propname='pore.viscosity', model=op.models.phase.viscosity.water_correlation)\n",
    "phase.regenerate_models()\n",
    "mean_vis = np.mean(phase['pore.viscosity'])\n",
    "print(f'mean of water viscosity is: {mean_vis*1000:.3f} mPa.s')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which matches with reported values of water viscosity at 298 K. Note that assigning the pressure values as gauge pressure  or assigning the temperature as Celsius results in an incorrect estimation of viscosity. The reason is the pore-scale model equations were defined based on absolute pressure and absolute temperature."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit conversion packages and challenges"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Different packages are available for unit conversions such as [unyt](https://unyt.readthedocs.io/en/stable/modules/unyt.html) and [Pint](https://pint.readthedocs.io/en/0.6/). Despite their broad applications and working with numpy, they were not included in the development of pore-scale models in OpenPNM, due to some challenges including additional overhead in calculations and regenerating models. However, these packages can be used to convert the units of a pre-defined array in a different unit to SI unit and using the resulting numpy array (SI units) for any purpose in pore network modeling."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
